package com.cy.study.service.impl;

import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.jwt.JWTUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cy.study.common.CommonConstant;
import com.cy.study.Enum.CommonEnum;
import com.cy.study.entity.MajorEntity;
import com.cy.study.entity.UserInfoEntity;
import com.cy.study.exception.BusinessException;
import com.cy.study.mapper.MajorMapper;
import com.cy.study.mapper.UserInfoMapper;
import com.cy.study.req.*;
import com.cy.study.res.UserDetailRes;
import com.cy.study.res.UserPageRes;
import com.cy.study.service.UserInfoService;
import com.cy.study.util.CacheTool;
import com.cy.study.util.PasswordEncodeUtil;
import com.cy.study.util.SecurityUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.cy.study.common.CommonConstant.HEADER_PATH;

@Service
@Slf4j
@RequiredArgsConstructor
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfoEntity> implements UserInfoService {

    private final CacheTool cacheTool;
    private final MajorMapper majorMapper;

    @Override
    public Integer userRegister(UserRegisterReq req) {
        //校验身份证号是否正确
        String regex = "^[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])\\d{3}([0-9Xx])$";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(req.getIdNo());
        Boolean isValid = matcher.matches();
        if(!isValid){
            throw new BusinessException("身份证号不符合格式");
        }
        QueryWrapper<UserInfoEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(UserInfoEntity::getTelephone,req.getTelephone());
        Long count = this.getBaseMapper().selectCount(wrapper);
        if(count>0){
            throw new BusinessException("该手机号已存在");
        }
        UserInfoEntity entity = new UserInfoEntity();
        BeanUtils.copyProperties(req,entity);
        //对密码进行加密处理
        String codePassword = PasswordEncodeUtil.passwordEncode(req.getPassword(), CommonConstant.PASSWORD_SALT);
        entity.setPassword(codePassword);
        //其它参数的填充
        entity.setRecFlag(CommonEnum.YES.getValue())
                .setMajorId(String.valueOf(req.getMajorId()))
                .setCreateTime(LocalDateTime.now())
                .setEditTime(LocalDateTime.now());
        //默认头像
        entity.setImgPath("base.jpeg");
        this.getBaseMapper().insert(entity);
        return entity.getId();
    }

    @Override
    public void uploadPic(MultipartFile file, Integer userId,Boolean isUpdate) {
        if(isUpdate){
            userId = SecurityUtils.getUserId();
        }
        //如果文件为空 报错
        if (file.isEmpty()) {
            throw new BusinessException("文件为空");
        }
        try {
            //获取项目当前路径
//            String url = "D:\\ideaProject";
            String url = HEADER_PATH;
            Path imgPath = Paths.get(url,null);
            // 检查文件夹是否存在，不存在则创建
            if (!Files.exists(imgPath)) {
                Files.createDirectories(imgPath);
            }
            //获取文件字节流文件
            byte[] bytes = file.getBytes();
            //文件id
            String randomString = UUID.randomUUID().toString();
            // 仅保留前 5 个字符作为随机字符串
            String newRan = randomString.substring(0, 5);
            String fileName = "userId"+newRan+"-"+userId+".jpg";
            // 构建保存文件的路径
            Path filePath = imgPath.resolve(fileName);
            // 将文件保存到本地
            Files.write(filePath, bytes);
            //更新数据库记录
            UserInfoEntity user = this.getBaseMapper().selectById(userId);
            user.setImgPath(fileName);
            this.saveOrUpdate(user);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public String userLogin(UserLoginReq req) {
        String telephone = req.getTelephone();
        String unCode = req.getPassword();
        String enCode = PasswordEncodeUtil.passwordEncode(unCode, CommonConstant.PASSWORD_SALT);
        QueryWrapper<UserInfoEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(UserInfoEntity::getTelephone,telephone)
                .eq(UserInfoEntity::getPassword,enCode);
        UserInfoEntity entity = this.getBaseMapper().selectOne(wrapper);
        if(ObjectUtil.isNull(entity)){
            throw new BusinessException("用户手机号或者密码错误");
        }
        Map<String,Object> payloads = new HashMap<>();
        payloads.put("userId",entity.getId());
        long l = System.currentTimeMillis() / 100 + CommonConstant.TOKEN_VALID_SECONDS;
        System.out.println(l);
        payloads.put("exp",l);
        String token = JWTUtil.createToken(payloads, CommonConstant.TOKEN_SIGN_KEY.getBytes());
        //加入缓存
        cacheTool.add(CommonConstant.TOKEN_PREFIX+entity.getId(),token);
        return token;
    }

    @Override
    public Page<UserPageRes> userPage(UserPageReq req) {
        Page page = new Page(req.getPageNum(),req.getPageSize());
        Page<UserPageRes> res = this.getBaseMapper().userPage(req,page);
        return res;
    }

    @Override
    public void changeStatus(UserStatusChangeReq req) {
        UserInfoEntity user = this.getBaseMapper().selectById(req.getId());
        if(user==null){
            throw new BusinessException("用户不存在");
        }
        if(user.getRecFlag()==1){
            user.setRecFlag(0);
        }else {
            user.setRecFlag(1);
        }
        saveOrUpdate(user);
    }

    @Override
    public UserDetailRes userDetail(Integer userId) {
        UserInfoEntity user = this.getBaseMapper().selectById(userId);
        UserDetailRes res = new UserDetailRes();
        MajorEntity major = majorMapper.selectById(user.getMajorId());
        BeanUtils.copyProperties(user,res);
        res.setMajorName(major.getMajorName());
        return res;
    }

    @Override
    public void updateInfo(UserUpdateInfoReq req) {
        Integer userId = SecurityUtils.getUserId();
        UserInfoEntity user = this.getById(userId);
        user.setNickName(req.getNickName());
        user.setTelephone(req.getTelephone());
        user.setMajorId(req.getMajorId());
        user.setSex(req.getSex());
        this.saveOrUpdate(user);
    }

    @Override
    public void updatePassword(UserUpdatePasswordReq req) {
        if(StrUtil.isBlank(req.getOldPassword())||StrUtil.isBlank(req.getNewPassword())){
            throw new BusinessException("旧密码或者新密码为空");
        }
        Integer userId = SecurityUtils.getUserId();
        UserInfoEntity entity = this.getById(userId);
        String codeOld = PasswordEncodeUtil.passwordEncode(req.getOldPassword(), CommonConstant.PASSWORD_SALT);
        if(!StrUtil.equals(codeOld,entity.getPassword())){
            throw new BusinessException("新旧密码不一致");
        }
        String newCode= PasswordEncodeUtil.passwordEncode(req.getNewPassword(),CommonConstant.PASSWORD_SALT);
        entity.setPassword(newCode);
        this.saveOrUpdate(entity);

    }

}
